home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games: Greatest Hits 1996 / Amiga Games: Greatest Hits 1996.iso / userbox / publicdomain / engclock_v7.0 / engclock7_source / engclock.c < prev    next >
C/C++ Source or Header  |  1996-05-19  |  34KB  |  1,161 lines

  1. /**********************************************/
  2. /*           English Clock 7.0                */
  3. /*           ==================               */
  4. /*                                            */
  5. /*          Coding: Ben Matthew               */
  6. /*            Date: (C) 1995                  */
  7. /*                                            */
  8. /*  based on an UNIX program of similar name  */
  9. /*                                            */
  10. /*    Compiled using SAS/C  by the SAS        */
  11. /*               Institute                    */
  12. /*                                            */
  13. /**********************************************/
  14.  
  15. static char *vers="$VER: English Clock 7.0 © Ben Matthew (19.05.96)";
  16.  
  17. #include "globals.h"
  18.  
  19. /* #define DEBUG_CODE */
  20.  
  21. int timerdev;
  22. struct MsgPort *TimerPort=NULL;
  23. BOOL cxsucc, rexxsucc;
  24.  
  25. extern char *__procname="EngClock_7.0";
  26. extern long __stack=5000;
  27.  
  28. /********* Main loop *************/
  29.  
  30. short main(int argc, char *argv[]) {
  31.     /* Stuff for timer */
  32.     int TimerSig;
  33.     struct Message *mess=NULL;
  34.     long sig, winsig, totalsig;
  35.     long cxsig, id, hot1sig, hot2sig, rexxsig;
  36.     /* Stuff for IDCMP */
  37.     ULONG class;
  38.     USHORT code;
  39.     /* Misc */
  40.     BOOL flag1=FALSE;
  41.     int mem1=70, mem2=70;
  42.     char newline[500];
  43.  
  44.     openall();    /* Opens all the libraries required */
  45.  
  46.     /* Get a lock on the screen we want to open the win on.. */
  47.     /* This lock will be held until we close to avoid nasty crashing ! */
  48.  
  49.     readprefs();
  50.     process_args(argc, argv);
  51.  
  52.     pubscreen=LockPubScreen(prefs.pub);
  53.     if(!pubscreen) {
  54.         msg("Cannot lock specified public screen!");
  55.         pubscreen=LockPubScreen(NULL);
  56.         if(!pubscreen) {
  57.             msg("Cannot lock Workbench!");
  58.             closeall();
  59.             return(0);
  60.         }
  61.     } 
  62.  
  63.     getscreentype(); /* Set up screentype structure */
  64.     getlocale();  /* Sets up the preferred language */
  65.     getfont();    /* Sets up the font structure */
  66.     setupmainwindow(); /* Sets up the win1 NewWindow structure */
  67.     changemenu(); /* Changes the menuitem structures to account font size */
  68.     
  69.     win_p = (struct Window *) OpenWindow ( &win1 );
  70.     if(!win_p) {
  71.         msg("Unable to open window!");
  72.         closeall();
  73.         return(0);
  74.     }
  75.     SetMenuStrip(win_p,&menu1);
  76.  
  77.     ispicture=loadpic(prefs.backdrop,pubscreen);
  78.  
  79.     /* Set up the timer.device */
  80.  
  81.     if(!(TimerPort=(struct MsgPort *)CreateMsgPort())) {
  82.         msg("Unable to open timer msg port!"); 
  83.         closeall();
  84.         return(0); 
  85.     }
  86.  
  87.     TimerSig=1L<<TimerPort->mp_SigBit;
  88.  
  89.     if(!(TimerIO=(struct timerequest *)CreateIORequest(TimerPort,sizeof(struct timerequest)))) {
  90.         msg("Problems with timer IO requests!!"); 
  91.         closeall();
  92.         return(0);
  93.     }
  94.  
  95.     if(timerdev=OpenDevice("timer.device",UNIT_WAITUNTIL,(struct IORequest *)TimerIO,0)) {
  96.         msg("Cannot open timer.device!"); 
  97.         closeall();
  98.         return(0); 
  99.     }
  100.  
  101.     TimerIO->tr_node.io_Command=TR_ADDREQUEST;
  102.     TimerIO->tr_time.tv_micro=0;
  103.  
  104.     TimerBase=(struct Library *)TimerIO->tr_node.io_Device;
  105.  
  106.     GetSysTime(&TimerIO->tr_time);
  107.     SendIO((struct IORequest *)TimerIO);
  108.  
  109.     /* End of timer bits */
  110.  
  111.     exit_flag=FALSE;
  112.     winsig=1<<win_p->UserPort->mp_SigBit;
  113.     totalsig=winsig|TimerSig;
  114.  
  115.     cxsucc=cxinit();
  116.     rexxsucc=arexxinit();
  117.  
  118.     if(cxsucc) {
  119.         cxsig=1<<CxMsgPort->mp_SigBit;
  120.         hot1sig=1<<CxHotKey1->mp_SigBit;
  121.         hot2sig=1<<CxHotKey2->mp_SigBit;
  122.         totalsig=totalsig|hot1sig|hot2sig|cxsig;
  123.     }
  124.     if(rexxsucc) {
  125.         rexxsig=1<<RexxPort->mp_SigBit;
  126.         totalsig=totalsig|rexxsig;
  127.     }
  128.  
  129.     while(exit_flag==FALSE) {
  130.         sig=Wait(totalsig);
  131.  
  132.         if(sig==TimerSig) {
  133.                         
  134.             gettime(); /* Set up the time structure */
  135.  
  136.             /* Make sure that at least one minute has passed before
  137.             refreshing the window or if language changed. */
  138.     
  139.             flag1=FALSE;
  140.  
  141.             if(time.hours!=mem2) flag1=TRUE;
  142.             if(time.minutes!=mem1) flag1=TRUE;
  143.             if(!flag1) goto break_away;
  144.             mem1=time.minutes; mem2=time.hours;
  145.     
  146.             refreshwindow();
  147.             goto break_away;
  148.         }  
  149.  
  150.         if(sig==winsig) {
  151.             while(message = (struct IntuiMessage *)GetMsg(win_p->UserPort)) {
  152.                 class=message->Class; code=message->Code;
  153.                 ReplyMsg((struct Message *)message);
  154.  
  155.  
  156.                 /* Now lets see what IDCMP message was sent: */
  157.                 switch (class) {
  158.                     case CLOSEWINDOW:
  159.                         exit_flag=TRUE;
  160.                     break;
  161.                     case NEWSIZE:
  162.                         refreshwindow();
  163.                     break;
  164.                     case MENUPICK:
  165.                         switch(ITEMNUM(code)) {
  166.                             case 0: /* Prefs  */
  167.                                 prefsgui();
  168.                                 ClearMenuStrip(win_p);
  169.                                 changemenu();
  170.                                 SetMenuStrip(win_p,&menu1);
  171.                                 ispicture=loadpic(prefs.backdrop,pubscreen);
  172.                                 refreshwindow();
  173.                             break;
  174.                             case 1: /* Jump */
  175.                                 jump();
  176.                                 refreshwindow();
  177.                             break;
  178.                             case 2: /* About */
  179.                                 about();
  180.                             break;
  181.                             case 3: /* Quit */
  182.                                 exit_flag=TRUE;
  183.                             break;
  184.                         }
  185.                     break;
  186.                 } /* End of Switch */
  187.             } /* End of while (GetMsg bit) */
  188.         }
  189.  
  190.         if(sig==cxsig) {
  191.             while(CxMessage=(CxMsg *)GetMsg(CxMsgPort)) {
  192.                 id=CxMsgID(CxMessage);
  193.                 ReplyMsg((struct Message *)CxMessage);
  194.                 
  195.                 switch(id) {
  196.                     case CXCMD_KILL:
  197.                         exit_flag=TRUE;
  198.                     break;
  199.                     case CXCMD_APPEAR:
  200.                         WindowToFront(win_p);
  201.                         prefsgui();
  202.                         ClearMenuStrip(win_p);
  203.                         changemenu();
  204.                         SetMenuStrip(win_p,&menu1);
  205.                         ispicture=loadpic(prefs.backdrop,pubscreen);
  206.                         refreshwindow();
  207.                     break;
  208.                     case CXCMD_DISABLE:
  209.                         // Wait for a CXCMD_ENABLE msg
  210.                         while(1) {
  211.                             WaitPort(CxMsgPort); 
  212.                             CxMessage=(CxMsg *)GetMsg(CxMsgPort);
  213.                             id=CxMsgID(CxMessage);
  214.                             ReplyMsg((struct Message *)CxMessage);
  215.                             if(id==CXCMD_ENABLE) break;
  216.                     }
  217.                     default:
  218.                     break;
  219.                 }
  220.             }
  221.         }
  222.     
  223.         if(sig==hot1sig) {
  224.             // Speak to me!
  225.             CxMessage=(CxMsg *)GetMsg(CxHotKey1);
  226.             if(CxMessage) ReplyMsg((struct Message *)CxMessage);
  227.             strcpy(newline,line1);
  228.             if(language==ENGLISH) newline[strlen(newline)-4]=NULL;  /* Get rid of pm/am */
  229.             strcat(newline,".  ");
  230.             if(prefs.date) {
  231.                 strcat(newline,line2);
  232.                 newline[strlen(newline)-6]=NULL; /* Get rid of year */
  233.             }
  234.             talk(trans(newline));
  235.         }        
  236.  
  237.         if(sig==hot2sig) {
  238.             // Open window
  239.             CxMessage=(CxMsg *)GetMsg(CxHotKey2);
  240.             if(CxMessage) ReplyMsg((struct Message *)CxMessage); 
  241.             WindowToFront(win_p);
  242.             prefsgui();
  243.             ClearMenuStrip(win_p);
  244.             changemenu();
  245.             SetMenuStrip(win_p,&menu1);
  246.             ispicture=loadpic(prefs.backdrop,pubscreen);
  247.             refreshwindow();
  248.         }
  249.  
  250.         if(sig==rexxsig)
  251.             process_arexx();
  252.                 
  253.         
  254.         break_away:
  255.         /* Reschedule the timer */
  256.         GetSysTime(&TimerIO->tr_time);
  257.         TimerIO->tr_time.tv_secs+=2;
  258.         TimerIO->tr_time.tv_micro=0;
  259.         SendIO((struct IORequest *)TimerIO);
  260.     }    /* End of while we havent quited bit */
  261.  
  262.     quitbit:
  263.  
  264.     closeall();
  265.     
  266.     return(0);
  267.  
  268. } /* End of main() */
  269.  
  270.  
  271. void gettime(void) {
  272.  
  273. /*****************************************/
  274. /*          Gettime() function           */
  275. /*          ==================           */
  276. /*                                       */
  277. /*        By Ben Matthew (C) 1995        */
  278. /*                                       */
  279. /*  Gettime() sets up the time structure */
  280. /*  according to the time stamp on the   */
  281. /*  IntuiMessage IntuiTicks bit          */
  282. /*                                       */
  283. /*****************************************/
  284.  
  285.     ULONG seconds,micros;
  286.     struct ClockData clock;
  287.  
  288.     CurrentTime(&seconds,µs);
  289.     Amiga2Date(seconds,&clock);    /* Utility.library function */
  290.  
  291.     time.seconds=clock.sec;
  292.     time.hours=clock.hour;
  293.     time.minutes=clock.min;
  294.     time.months=clock.month;
  295.     time.years=clock.year;
  296.     time.days=clock.mday;
  297.     time.wday=clock.wday;
  298. }
  299.  
  300. short readprefs(void) {
  301.    int bytes=0, i;
  302.  
  303.    handle=Open(PREFS_FILE,MODE_OLDFILE);
  304.    if(!handle) {
  305.       /* Preferences file NOT found, so set default settings... */
  306.       prefs.x=0;prefs.y=0;prefs.width=370;prefs.height=32;
  307.       prefs.planguage=1;
  308.       for(i=0; i<8; i++) {
  309.          prefs.date_col[i]=1;
  310.          prefs.time_col[i]=1;
  311.       }
  312.       prefs.just=0;
  313.         for(i=0; i<11; i++) {
  314.             prefs.events[i].used=FALSE;
  315.             prefs.events[i].type=0;
  316.             prefs.events[i].hours=1;
  317.             prefs.events[i].minutes=0;
  318.             prefs.events[i].timecode=1;
  319.             strcpy(prefs.events[i].message,"");
  320.             prefs.events[i].day=1;
  321.             prefs.events[i].month=1;
  322.             prefs.events[i].year=1995;
  323.             prefs.events[i].enabledate=FALSE;
  324.        }
  325.         prefs.date=FALSE;
  326.         prefs.wtf=FALSE;
  327.         prefs.autoadjust=FALSE;
  328.         strcpy(prefs.backdrop,"");
  329.         strcpy(prefs.pub,"");
  330.         strcpy(prefs.accent,"locale:accents/english.accent");
  331.         strcpy(prefs.hkey,"CONTROL ALT e");
  332.         strcpy(prefs.tkey,"HELP");
  333.       return(0);
  334.    }
  335.    /* If not returned by now, preferences file is open! */
  336.  
  337.    bytes=FRead(handle,(char *)&prefs,1,sizeof(prefs));
  338.    if(bytes!=sizeof(prefs)) {
  339.       /* Error reading prefs file */
  340.       DisplayBeep(NULL);
  341.       /* Set the default settings */
  342.       prefs.x=0;prefs.y=0;prefs.width=370;prefs.height=32;
  343.       prefs.planguage=1;
  344.       for(i=0; i<8; i++) {
  345.          prefs.date_col[i]=1;
  346.          prefs.time_col[i]=1;
  347.       }
  348.       prefs.just=0;
  349.         for(i=0; i<11; i++) {
  350.             prefs.events[i].used=FALSE;
  351.             prefs.events[i].type=0;
  352.             prefs.events[i].hours=1;
  353.             prefs.events[i].minutes=0;
  354.             prefs.events[i].timecode=1;
  355.             strcpy(prefs.events[i].message,"");
  356.             prefs.events[i].day=1;
  357.             prefs.events[i].month=1;
  358.             prefs.events[i].year=1995;
  359.             prefs.events[i].enabledate=FALSE;
  360.        }
  361.         prefs.date=FALSE;
  362.         prefs.wtf=FALSE;
  363.         prefs.autoadjust=FALSE;
  364.         strcpy(prefs.backdrop,"");
  365.         strcpy(prefs.pub,"");
  366.         strcpy(prefs.accent,"locale:accents/english.accent");
  367.         strcpy(prefs.hkey,"CONTROL ALT e");
  368.         strcpy(prefs.tkey,"HELP");
  369.     }
  370.    if(strcmp(prefs.header,ID)) {
  371.        DisplayBeep(NULL);
  372.        msg("Error: Corrupt preferences header!");
  373.    }
  374.    Close(handle);
  375.    return(0);
  376. }
  377.  
  378. void setupengnums(void) {
  379. /********************************************************************/
  380. /*                        Set up Engnums                            */
  381. /*                        ==============                            */
  382. /*                                                                  */
  383. /*   This function sets up the engnums[] array with whatever        */
  384. /*   preferred language has been specified by language.  This       */
  385. /*   function also sets up the line1 string which contains the      */
  386. /*   text which is displayed in the window.  Being a nice modular   */
  387. /*   function this enables me to add in more supported languages    */
  388. /*   later!                                                         */
  389. /*                                                                  */
  390. /********************************************************************/
  391.  
  392.    int temp1;
  393.  
  394.    if(time.hours>12) {
  395.          time.hours=time.hours-12;
  396.          afternoon=TRUE;
  397.    }
  398.    else {
  399.       if(time.hours==12)
  400.          afternoon=TRUE;
  401.       else
  402.          afternoon=FALSE;
  403.    }
  404.    if(time.hours==0)  /* Midnight! */
  405.          time.hours=12;
  406.    switch(language) {
  407.       case ENGLISH:
  408.          strcpy(line1,"It's"); 
  409.  
  410.          engnums[1]="one"; engnums[2]="two";
  411.          engnums[3]="three";
  412.          engnums[4]="four"; engnums[5]="five"; engnums[6]="six";
  413.          engnums[7]="seven"; engnums[8]="eight";
  414.          engnums[9]="nine"; engnums[10]="ten";
  415.          engnums[11]="eleven"; engnums[12]="twelve";
  416.          engnums[13]="midnight"; engnums[14]="midday"; /* Special refs */
  417.          engnums[15]="quarter"; engnums[20]="twenty";
  418.          engnums[25]="twenty-five"; engnums[30]="half";
  419.          engnums[35]="five and twenty"; engnums[40]="twenty";
  420.          engnums[45]="quarter"; engnums[50]="ten";
  421.          engnums[55]="five";
  422.          temp1=(time.minutes/5)*5;
  423.          if((time.minutes-temp1)<=2) {
  424.             strcat(line1," just gone");
  425.          }
  426.          else {
  427.             strcat(line1," nearly");
  428.          }
  429.          if(time.minutes>2 & time.minutes<58) {
  430.             strcat(line1," "); 
  431.             if((time.minutes-temp1)<=2) {
  432.                strcat(line1,engnums[(time.minutes/5)*5]);
  433.             }
  434.             else {
  435.                strcat(line1,engnums[((time.minutes/5)+1)*5]);
  436.             }
  437.          }
  438.          if(time.minutes>2 & time.minutes<58) {
  439.             if(time.minutes<=32) {
  440.                strcat(line1," past");
  441.             }
  442.             else {
  443.                strcat(line1," to");
  444.             }
  445.          }
  446.          strcat(line1," "); 
  447.          if(time.minutes<=32) {
  448.             if(time.hours==12) {
  449.                if(afternoon) {
  450.                   if(time.minutes>2) {
  451.                      strcat(line1,engnums[14]);
  452.                   }
  453.                   else {
  454.                      strcat(line1,engnums[12]);
  455.                   }
  456.                }
  457.                else {
  458.                   if(time.minutes>2) {
  459.                      strcat(line1,engnums[13]);
  460.                   }
  461.                   else {
  462.                      strcat(line1,engnums[12]);
  463.                   }
  464.                }
  465.             } else {
  466.                strcat(line1,engnums[time.hours]);
  467.             }
  468.          } else {
  469.             if(time.hours==12) {
  470.                strcat(line1,engnums[1]);
  471.             }
  472.             else {
  473.                if(time.hours==11) {
  474.                   if(afternoon) {
  475.                      if(time.minutes<58) {
  476.                         strcat(line1,engnums[13]);
  477.                      }
  478.                      else {
  479.                         strcat(line1,engnums[12]);
  480.                      }
  481.                   }
  482.                   else {
  483.                      if(time.minutes<58) {
  484.                         strcat(line1,engnums[14]);
  485.                      }
  486.                      else {
  487.                         strcat(line1,engnums[12]);
  488.                      }
  489.                   }
  490.                }
  491.                else {
  492.                   strcat(line1,engnums[time.hours+1]);
  493.                }
  494.             }
  495.          }
  496.          if((time.minutes<3) | (time.minutes>57) ) {
  497.             strcat(line1," o'clock");
  498.          }
  499.  
  500.          if(afternoon)
  501.             strcat(line1," (pm)");
  502.          else
  503.             strcat(line1," (am)");
  504.  
  505.          if(time.hours!=12 & !(time.hours==11 & time.minutes>57) ) {
  506.  
  507.          break; /* End of english defines */
  508.  
  509.       case FRENCH:
  510.          strcpy(line1,"Il est");
  511.          engnums[1]="un"; engnums[2]="deux";
  512.          engnums[3]="trois";
  513.          engnums[4]="quatre"; engnums[5]="cinq"; engnums[6]="six";
  514.          engnums[7]="sept"; engnums[8]="huit";
  515.          engnums[9]="neuf"; engnums[10]="dix";
  516.          engnums[11]="onze"; engnums[12]="douze";
  517.          engnums[15]="et quart"; engnums[20]="vingt";
  518.          engnums[25]="vingt-cinq"; engnums[30]="et demie";
  519.          engnums[35]="vingt-cinq"; engnums[40]="vingt";
  520.          engnums[45]="quart"; engnums[50]="dix";
  521.          engnums[55]="cinq";
  522.          temp1=(time.minutes/5)*5;
  523.          if((time.minutes-temp1)>2)
  524.             strcat(line1," bientôt");
  525.          strcat(line1," ");
  526.             if(time.minutes<=32) {
  527.                strcat(line1,engnums[time.hours]);
  528.             }
  529.             else {
  530.                if(time.hours==12) {
  531.                   strcat(line1,engnums[1]); }
  532.                else {
  533.             strcat(line1,engnums[time.hours+1]);
  534.             }
  535.          }
  536.          strcat(line1," heures");
  537.          if(time.minutes>2 & time.minutes<58) {
  538.             strcat(line1," ");
  539.             if(time.minutes>32)
  540.                   strcat(line1,"moins ");
  541.             if((time.minutes-temp1)<=2) {
  542.                strcat(line1,engnums[(time.minutes/5)*5]); }
  543.             else {
  544.                strcat(line1,engnums[((time.minutes/5)+1)*5]); }
  545.          }
  546.          if((time.minutes-temp1)<=2)
  547.             strcat(line1," passées");
  548.          break; /* End of french defines */
  549.          case SPANISH:
  550.             if((time.hours==1) || (time.hours==12 && time.minutes >= 33)) 
  551.                 strcpy(line1,"Es la ");
  552.                 /* Could add at this point aproximadamente, but +100 pixels */
  553.             else
  554.                 strcpy(line1,"Son las ");
  555.          engnums[1]="una"; engnums[2]="dos";
  556.          engnums[3]="tres";
  557.          engnums[4]="cuatro"; engnums[5]="cinco"; engnums[6]="seis";
  558.          engnums[7]="siete"; engnums[8]="ocho";
  559.          engnums[9]="nueve"; engnums[10]="diez";
  560.          engnums[11]="once"; engnums[12]="doce";
  561.          engnums[15]="cuarto"; engnums[20]="veinte";
  562.          engnums[25]="veinticinco"; engnums[30]="media";
  563.          engnums[35]="veinticinco"; engnums[40]="veinte";
  564.          engnums[45]="cuarto"; engnums[50]="diez";
  565.          engnums[55]="cinco";
  566.          temp1=(time.minutes/5)*5;
  567.             if(time.minutes<=32)
  568.                strcat(line1,engnums[time.hours]);
  569.             else {
  570.                if(time.hours==12)
  571.                   strcat(line1,engnums[1]);
  572.                else
  573.                   strcat(line1,engnums[time.hours+1]);
  574.             }
  575.          if(time.minutes>2 & time.minutes<58) {
  576.             if(time.minutes<=32)
  577.                strcat(line1," y");
  578.             else
  579.                strcat(line1," menos");
  580.             strcat(line1," ");
  581.             if((time.minutes-temp1)<=2) {
  582.                strcat(line1,engnums[(time.minutes/5)*5]); }
  583.             else {
  584.                strcat(line1,engnums[((time.minutes/5)+1)*5]); }
  585.          }
  586.          strcat(line1," "); 
  587.  
  588.             if(!afternoon) {
  589.                 /* Morning (AM) */
  590.                     if( (time.hours==12 && time.minutes >= 33) ||
  591.                          (time.hours==4 && time.minutes <= 32) ||
  592.                          (time.hours >= 1 && time.hours <= 3)
  593.                      ) strcat(line1,"de la magruda");
  594.  
  595.                     if( (time.hours==4 && time.minutes >=33) ||
  596.                          (time.hours==11 && time.minutes <= 32) ||
  597.                          (time.hours >= 5 && time.minutes <= 10)
  598.                      ) strcat(line1,"de la mañana");
  599.  
  600.                     if(time.hours==11 && time.minutes >=33) strcat(line1,"del mediodia");
  601.             
  602.             } else {
  603.                 /* Afternoon/Evening (PM) */
  604.                 
  605.                 if(time.hours==12 && time.minutes <=32) strcat(line1,"de la noche");
  606.  
  607.                 if( (time.hours==12 && time.minutes >=33) ||
  608.                      (time.hours==8 && time.minutes <= 32) ||
  609.                      (time.hours >= 1 && time.hours <= 7)
  610.                  ) strcat(line1,"de la tarde");
  611.  
  612.                 if( (time.hours==8 && time.minutes >=33) ||
  613.                      (time.hours==11 && time.minutes <= 32) ||
  614.                      (time.hours >= 9 && time.hours <= 10)
  615.                  ) strcat(line1,"de la noche");
  616.  
  617.                 if( (time.hours==11 && time.minutes >=33) ||
  618.                      (time.hours==12 && time.minutes <=32)
  619.                  ) strcat(line1,"del mediodia");
  620.             }
  621.    
  622.          break; /* End of spanish defines */
  623.         }
  624.  
  625.    } /* end of switch */
  626. } /* end of function */
  627.  
  628. void getfont(void) {
  629.  
  630. /***************************************************/
  631. /*              Get Font Dimensions                */
  632. /*              ===================                */
  633. /*                                                 */
  634. /* This routine finds out what the default font is */
  635. /* and sets up the structure "font" with the       */
  636. /* dimensions of the default font                  */
  637. /*                                                 */
  638. /***************************************************/
  639.  
  640.    font.x=GfxBase->DefaultFont->tf_XSize;
  641.    font.y=GfxBase->DefaultFont->tf_YSize;
  642.  
  643. }
  644.  
  645. void openall(void) {
  646.  
  647. /**********************************************************/
  648. /*             Open all libraries and devices             */
  649. /*             ==============================             */
  650. /*                                                        */
  651. /*  A very simple routine that opens all the libraries    */
  652. /*  and devices needed by the program.  All the           */
  653. /*  open library/device reqeusts are tested individually  */
  654. /*  since it helps if I know what library/device didn't   */
  655. /*  open when testing                                     */
  656. /**********************************************************/
  657.  
  658.    /* Some functions used in this program are illegal under KS1.3 so
  659.       just do a quick check to make sure we are running OS 2.x+ */
  660.  
  661.    /* if(SysBase->LibNode.lib_Version<37) {
  662.       msg("EngClock requires OS 2.0 or higher to run!");
  663.       closeall();
  664.       exit(NULL);
  665.    } */
  666.  
  667.     // Set up global bases
  668.  
  669.     IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0);
  670.     GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0);
  671.     DiskfontBase=OpenLibrary("diskfont.library",0);
  672.     GadToolsBase=OpenLibrary("gadtools.library",0);
  673.     UtilityBase=OpenLibrary("utility.library",0);
  674.     CxBase=OpenLibrary("commodities.library",0);
  675.  
  676.     if(!(IntuitionBase && GfxBase && DiskfontBase && GadToolsBase && UtilityBase)) {
  677.         msg("Unable to open needed libs!");
  678.         closeall();
  679.         exit(NULL);
  680.     }
  681.  
  682.     /* This just wakes up narrator device if available */
  683.     talk(" ");
  684. }
  685.  
  686. void closeall(void) {
  687.  
  688. /************************************************************/
  689. /*              Close all libraries and devices             */
  690. /*              ===============================             */
  691. /*                                                          */
  692. /*  This simple routine is the opposite to openall().  It   */
  693. /*  closes any libraries/devices that have been opened by   */
  694. /*  the program.  Each library is tested before closing.    */
  695. /************************************************************/
  696.  
  697.     int retry=0;
  698.  
  699.     if(ispicture) unloadpic(piccy);
  700.     
  701.     if(pubscreen) UnlockPubScreen(NULL,pubscreen);
  702.  
  703.     if(win_p) {
  704.         ClearMenuStrip(win_p);
  705.         CloseWindow(win_p);
  706.     }
  707.     if(!timerdev) CloseDevice((struct IORequest *)TimerIO);
  708.     if(TimerIO) DeleteIORequest(TimerIO);
  709.     
  710.     if(TimerPort) 
  711.         DeleteMsgPort(TimerPort);
  712.     
  713.     if(cxsucc) cxclose();
  714.     if(rexxsucc) arexxclose();
  715.  
  716.     if(UtilityBase) CloseLibrary(UtilityBase);
  717.     if(GfxBase) CloseLibrary((struct Library *)GfxBase);
  718.     if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  719.     if(GadToolsBase) CloseLibrary(GadToolsBase);
  720.     if(DiskfontBase) CloseLibrary(DiskfontBase);
  721.     if(CxBase)    CloseLibrary(CxBase);
  722.  
  723. }
  724.  
  725. void clearwindow(void) {
  726.  
  727. /*********************************************/
  728. /*               Clear Window                */
  729. /*               ============                */
  730. /*                                           */
  731. /* A very simple routine to clear the main   */
  732. /* window of everything its got!  Part of    */
  733. /* English Clock's refresh routine.  New     */
  734. /* V2.5 feature is that it is now properly   */
  735. /* font sensitive!!                          */
  736. /*********************************************/
  737.  
  738.    int x,y,width,height;
  739.  
  740.    y=screentype.s_bar+2;  /* Allow 2 more pixels to be safe */
  741.    x=6; /* Allow room for the fixed width left window line */
  742.    width=win_p->Width-20; /* Allow room for the bigger right line */
  743.    height=win_p->Height-3; /* Allow room for the thin bottom line */
  744.     
  745.     if(ispicture) {
  746.       pattern(win_p,pubscreen,piccy);
  747.    }
  748.    else {
  749.       SetAPen(win_p->RPort,0);
  750.       RectFill(win_p->RPort,x,y,width,height);
  751.       SetAPen(win_p->RPort,1);
  752.    }
  753.  
  754. }
  755.  
  756. short setupmainwindow(void) {
  757.  
  758. /**************************************************/
  759. /*            Set up main window                  */
  760. /*            ==================                  */
  761. /*                                                */
  762. /*  This routine makes the main window assignment */
  763. /*  Note that no globally braced assignment is    */
  764. /*  defined previous since for some reason if you */
  765. /*  touch a NewWindow struct after globally       */
  766. /*  assigning it then all hell breaks loose!      */
  767. /**************************************************/
  768.  
  769. /* Note to coders:  Okay I know that there is probably a much easier and
  770.    nicer way to do this then below but who cares?!!?  It works dunnit? */
  771.  
  772.    BOOL screenflag=FALSE;
  773.  
  774.    /* Stuff at beginning (LeftEdge...) assigned below */
  775.  
  776.    win1.DetailPen=0;
  777.    win1.BlockPen=1;
  778.    win1.IDCMPFlags=CLOSEWINDOW|MENUPICK|NEWSIZE;
  779.    win1.Flags=SMART_REFRESH|WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH|WINDOWSIZING|ACTIVATE;
  780.    win1.FirstGadget=NULL;
  781.    win1.CheckMark=NULL;
  782.    win1.Title="English Clock 7.0 © 1996 by Ben Matthew";
  783.         if(language==SPANISH)
  784.             win1.Title="English Clock 7.0 © 1996 por Ben Matthew";
  785.    win1.Screen=pubscreen;
  786.    win1.BitMap=NULL;
  787.    win1.MaxWidth=640;
  788.    win1.MaxHeight=256;  /* This should be enough for any font size! */
  789.    win1.Type=CUSTOMSCREEN;
  790.  
  791. /* First change the window dimensions to the ones specified by prefs */
  792.  
  793. win1.LeftEdge=prefs.x;
  794. win1.TopEdge=prefs.y;
  795. win1.Width=prefs.width;
  796. win1.Height=prefs.height;
  797.  
  798. /* The next bit is a wee bit more complex since it has to take into
  799.    account the font size and what not */
  800.  
  801. /* The maximum length that the time can be is:
  802.  
  803.       English = 47 total characters */
  804.  
  805. /* The minimum is 23 chars */
  806.  
  807. /* Hokay, I have had a brainwave!!  Why dont we be nice and allow users
  808.    who have huge res workbenches to enlarge their windows even more!! */
  809.  
  810. win1.MaxWidth=screentype.s_width;
  811. win1.MaxHeight=screentype.s_height;
  812.  
  813. if(prefs.autoadjust) {
  814.     win1.MinHeight=screentype.s_bar+font.y+5;
  815.     win1.MinWidth=40;
  816.     return(1);  
  817. }
  818.  
  819. win1.MinWidth=(47*font.x)+40;  /* Leave 40 to be sure */
  820.  
  821. if(prefs.date)
  822.    win1.MinHeight=(font.y*2)+screentype.s_bar+16;
  823. else
  824.    win1.MinHeight=font.y+screentype.s_bar+16;
  825.  
  826.  
  827. /* Now if a particularly font is used and the above calculation creates
  828.    Minimum values larger than can be displayed on the current screen then
  829.    EngClock refuses to open and doesn't close the libs proper - not very
  830.    nice!! So do a quick check!! */
  831.  
  832.  
  833. if(win1.MinWidth > screentype.s_width)
  834.    screenflag=TRUE;
  835. if(win1.MinHeight > screentype.s_height)
  836.    screenflag=TRUE;
  837. if(screenflag) {
  838.    msg("Sorry but your screen dimension is too small for EngClock to use with your current font size!");
  839.    closeall();
  840.    exit(NULL);
  841. }
  842.  
  843. /* Do a quick check to make sure that the current width and height do not
  844.    exceed the max (+vv).  This should NEVER happen but it could if someone
  845.    or something tampers with the preferences file! */
  846.  
  847.  
  848. if(win1.Width > win1.MaxWidth) win1.Width=win1.MaxWidth;
  849. if(win1.Height > win1.MaxHeight) win1.Height=win1.MaxHeight;
  850.  
  851. if(win1.Width < win1.MinWidth) win1.Width=win1.MinWidth;
  852. if(win1.Height < win1.MinHeight) win1.Height=win1.MinHeight;
  853.  
  854. /* Now check if the window is in the right place */
  855.  
  856. while (win1.LeftEdge+win1.Width > screentype.s_width) {
  857.    win1.LeftEdge--;
  858.    if (win1.LeftEdge== -1) {
  859.       msg("Window too big for screen!");
  860.       closeall();
  861.       exit(NULL);
  862.    }
  863. }
  864.  
  865. while (win1.TopEdge+win1.Height > screentype.s_height) {
  866.    win1.TopEdge--;
  867.    if (win1.TopEdge== -1) {
  868.       msg("Window too big for screen!");
  869.       closeall();
  870.       exit(NULL);
  871.    }
  872. }
  873.  
  874. /* Right then, all done.  Return and let main() do its stuff!! */
  875.  
  876. return(0);
  877.  
  878. }
  879.  
  880. short changemenu(void) {
  881.  
  882.    /* Function changes the Height elements of the MenuItems so that it
  883.       takes into account font sizes */
  884.  
  885.    int height;
  886.    height = screentype.s_bar; /* Allow a bit of space top and bot */
  887.  
  888.     switch(language) {
  889.         case ENGLISH:
  890.             menu1.MenuName="Project";
  891.             menu_text1.IText="Set Prefs...";
  892.             menu_text2.IText="Jump";
  893.             menu_text3.IText="About...";
  894.             menu_text4.IText="Quit";
  895.             menu_item1.Command='S';
  896.             menu_item2.Command='J';
  897.             menu_item3.Command='A';
  898.             menu_item4.Command='Q';
  899.         break;
  900.         case FRENCH:
  901.             menu1.MenuName="Projet";
  902.             menu_text3.IText="Autour";
  903.             menu_text2.IText="Sauter";
  904.             menu_text4.IText="Quitte";
  905.             menu_text1.IText="Ensemble...";
  906.             menu_item1.Command='E';
  907.             menu_item2.Command='S';
  908.             menu_item3.Command='A';
  909.             menu_item4.Command='Q';
  910.         break;
  911.         case SPANISH:
  912.             menu1.MenuName="Proyecto";
  913.             menu_text3.IText="Sobre...";
  914.             menu_text2.IText="Ir a pantalla";
  915.             menu_text4.IText="Salir";
  916.             menu_text1.IText="Prefs...";
  917.             menu_item1.Command='P';
  918.             menu_item2.Command='I';
  919.             menu_item3.Command='?';
  920.             menu_item4.Command='S';
  921.         break;
  922.  
  923.         default:
  924.             msg("Internal error (language !=1,2,3)");
  925.         break;
  926.     }
  927.    menu_item1.Height=height; /* First item in first menu */
  928.    menu_item2.Height=height; menu_item2.TopEdge=height;
  929.    menu_item3.Height=height; menu_item3.TopEdge=(height*2);
  930.    menu_item4.Height=height; menu_item4.TopEdge=(height*3);
  931.  
  932.    /* Menu 1 = Project (7), Menu 2 = Preferences (11) */
  933.  
  934.    /* Note that I am being forced to make the assumption that the font
  935.       being used for the windows has the same width and height dimensions
  936.       although this is highly unlikely I cannot find a way to locate this
  937.       other measurement */
  938.  
  939.  
  940.    menu1.Width=(7*(screentype.s_bar-2))+5;
  941.  
  942.    /* Changes widths to be font sensitive + allow hotkey spacing */
  943.  
  944.    menu_item1.Width=(19*(screentype.s_bar-2))+COMMWIDTH;
  945.    menu_item2.Width=(19*(screentype.s_bar-2))+COMMWIDTH;
  946.    menu_item3.Width=(19*(screentype.s_bar-2))+COMMWIDTH;
  947.    menu_item4.Width=(19*(screentype.s_bar-2))+COMMWIDTH;
  948.  
  949.    if((19*(screentype.s_bar-2))+COMMWIDTH > screentype.s_width) {
  950.       msg("Font size is too big to create menus!!");
  951.       closeall();
  952.       exit(NULL);
  953.    }
  954.  
  955. return(0);
  956.  
  957. }
  958.  
  959. short refreshwindow(void) {
  960.    /* Simple routine which calls funcs that together redraw the main
  961.       window.  Placed in its own function as of version 2.6 so that I
  962.       can redraw the window's contents any time I want, esp. with NEWSIZE */
  963.  
  964.    int length, space_avail;
  965.  
  966.    setupengnums();
  967.    if(language==1) setupdate_english();
  968.    if(language==2) setupdate_french();
  969.    if(language==3) setupdate_spanish();
  970.  
  971.  
  972.    if(prefs.wtf)
  973.       WindowToFront(win_p);
  974.  
  975.     int_text.IText=line1;
  976.    date_text.IText=line2;
  977.  
  978.     if(prefs.autoadjust)
  979.         autoadjust();    
  980.     else {
  981.         // Make sure that the MinWidths are not set for autoadjust
  982.         if(win_p->MinWidth != (47*font.x)+40) {
  983.             // N.B Not checking MinHeight due to complicated routine
  984.             // Update win1
  985.             win1.LeftEdge=win_p->LeftEdge;
  986.             win1.TopEdge=win_p->TopEdge;
  987.             win1.Height=win_p->Height;
  988.             win1.Width=win_p->Width;
  989.  
  990.             win1.MinWidth=(47*font.x)+40;
  991.             if(prefs.date)
  992.                win1.MinHeight=(font.y*2)+screentype.s_bar+16;
  993.             else
  994.                win1.MinHeight=font.y+screentype.s_bar+16;
  995.  
  996.             ClearMenuStrip(win_p);
  997.             CloseWindow(win_p);
  998.         
  999.             if(!(win_p=OpenWindow(&win1))) {
  1000.                 // There is no reason why this should fail since we updated
  1001.                 msg("Error re-opening window (system failure!!)");
  1002.                 closeall();    
  1003.                 exit(NULL);
  1004.             }
  1005.             SetMenuStrip(win_p,&menu1);
  1006.         }
  1007.     }
  1008.         switch(prefs.just) {
  1009.             case 0: /* Left */
  1010.                 int_text.LeftEdge=16;
  1011.                 date_text.LeftEdge=16;
  1012.             break;
  1013.             case 1: /* Centre */
  1014.                 length=strlen(line1)*font.x;
  1015.                 space_avail=win_p->Width-26;
  1016.                 int_text.LeftEdge=(space_avail-length)/2;
  1017.                 length=strlen(line2)*font.x;
  1018.                 date_text.LeftEdge=(space_avail-length)/2;
  1019.             break;
  1020.             case 2: /* Right */
  1021.                 length=strlen(line1)*font.x;
  1022.                 space_avail=win_p->Width-26;
  1023.                 int_text.LeftEdge=space_avail-length;
  1024.                 length=strlen(line2)*font.x;
  1025.                 date_text.LeftEdge=space_avail-length;
  1026.             break;
  1027.         }
  1028.     
  1029.  
  1030.  
  1031.    
  1032.    clearwindow();
  1033.    if(prefs.date) {
  1034.       if(((win_p->MinHeight < (screentype.s_bar+(font.y*2)+16)) &&!(prefs.autoadjust)) || (prefs.autoadjust && (win_p->Height < (screentype.s_bar+(font.y*2)+16))) ) {
  1035.          /* Update the win1 structure to accomodate the new win_p dimensions */
  1036.          win1.TopEdge=win_p->TopEdge;
  1037.     win1.LeftEdge=win_p->LeftEdge;
  1038.     win1.Width=win_p->Width;
  1039.     win1.Height=win_p->Height;
  1040.          ClearMenuStrip(win_p);
  1041.          CloseWindow(win_p);
  1042.          if(!prefs.autoadjust) 
  1043.         win1.MinHeight=screentype.s_bar+(font.y*2)+16;
  1044.          win1.Height=screentype.s_bar+(font.y*2)+16;
  1045.          while ((win1.TopEdge+win1.Height) > screentype.s_height) {
  1046.             win1.TopEdge--;
  1047.             if(win1.TopEdge < 0) {
  1048.                DisplayBeep(NULL);
  1049.                closeall();
  1050.                exit(NULL);
  1051.             }
  1052.          }
  1053.          win_p=OpenWindow(&win1);
  1054.          SetMenuStrip(win_p,&menu1);
  1055.          if(!win_p) {
  1056.             DisplayBeep(NULL);
  1057.             closeall();
  1058.             exit(NULL);
  1059.          }
  1060.          SetMenuStrip(win_p,&menu1); 
  1061.       }
  1062.     date_text.TopEdge=(((win_p->Height-((2*font.y)+(screentype.s_bar-6)))/2)+font.y);
  1063.     int_text.TopEdge=((win_p->Height-((2*font.y)+(screentype.s_bar-6)))/2)-2;
  1064.  
  1065.       date_text.FrontPen=prefs.date_col[screentype.s_mode];
  1066.       PrintIText(win_p->RPort,&date_text,0,screentype.s_bar-2);
  1067.    } else {
  1068.       /* Only one line needed */
  1069.       if(win_p->MinHeight > (screentype.s_bar+16+font.y)) {
  1070.          ClearMenuStrip(win_p);
  1071.          CloseWindow(win_p);
  1072.          win1.MinHeight=screentype.s_bar+16+font.y;
  1073.          win1.Height=screentype.s_bar+16+font.y;
  1074.          win_p=OpenWindow(&win1);
  1075.          if(!win_p) {
  1076.             DisplayBeep(NULL);
  1077.             closeall();
  1078.             exit(NULL);
  1079.          }
  1080.          SetMenuStrip(win_p,&menu1);
  1081.       }
  1082.     int_text.TopEdge=((win_p->Height-font.y-screentype.s_bar)/2)+2;
  1083.    }
  1084.    int_text.FrontPen=prefs.time_col[screentype.s_mode];
  1085.     
  1086.    PrintIText(win_p->RPort,&int_text,0,screentype.s_bar-2);
  1087.     process_alarm();
  1088.  
  1089.    return(0);
  1090. }
  1091.  
  1092. void setupdate_english(void) {
  1093.    char tmp[10];
  1094.  
  1095.    strcpy(line2,days_data[time.wday]);
  1096.  
  1097.     switch(time.days) {
  1098.       case 1:
  1099.          /* First day */
  1100.          strcat(line2," 1st ");
  1101.       break;
  1102.       case 2:           
  1103.          strcat(line2," 2nd ");
  1104.       break;
  1105.       case 3:
  1106.          strcat(line2," 3rd ");
  1107.       break;
  1108.       case 21:
  1109.          strcat(line2," 21st ");
  1110.       break;
  1111.       case 22:
  1112.          strcat(line2," 22nd ");
  1113.       break;
  1114.       case 23:
  1115.          strcat(line2," 23rd ");
  1116.       break;
  1117.       case 30:
  1118.          strcat(line2," 30th ");
  1119.       break; 
  1120.       case 31:
  1121.          strcat(line2," 31st ");
  1122.       break;
  1123.       default:
  1124.          sprintf(tmp," %ld",time.days);
  1125.          strcat(line2,tmp);
  1126.          strcat(line2,"th ");
  1127.       break;
  1128.    } /* End of switch(time.days) */
  1129.    strcat(line2,months_data[time.months]);
  1130.    strcat(line2,", "); 
  1131.    sprintf(tmp,"%ld",time.years);
  1132.    strcat(line2,tmp);
  1133. } /* End of ENGLISH */
  1134.  
  1135.  
  1136. void setupdate_spanish(void) {
  1137.    char tmp[10]; 
  1138.    strcpy(line2,days_data_spanish[time.wday]);
  1139.    strcat(line2,",");
  1140.    sprintf(tmp," %ld ",time.days);
  1141.    strcat(line2,tmp); 
  1142.    strcat(line2,"de ");
  1143.    strcat(line2,months_data_spanish[time.months]);
  1144.    strcat(line2," de");
  1145.    sprintf(tmp," %ld",time.years);
  1146.    strcat(line2,tmp); 
  1147.  
  1148. }
  1149.  
  1150. void setupdate_french(void) {
  1151.    char tmp[10];
  1152.  
  1153.    strcpy(line2,days_data_french[time.wday]);
  1154.    sprintf(tmp," %ld ",time.days);
  1155.    strcat(line2,tmp);
  1156.    strcat(line2,months_data_french[time.months]);
  1157.    sprintf(tmp,", %ld",time.years);
  1158.    strcat(line2,tmp);
  1159. } /* End of French */
  1160.  
  1161.